package com.hk.aspect;

import cn.hutool.json.JSONUtil;
import com.hk.Enume.OperationType;
import com.hk.annotation.AotoFile;
import com.hk.constant.AutoFillConstant;
import com.hk.constant.PathConstant;
import com.hk.context.BaseContext;
import com.hk.core.UserUtlis;
import com.hk.domain.OperLog;
import com.hk.service.LogService;
import com.hk.utils.IpLocationUtil;
import com.hk.utils.IpUtils;
import com.hk.utils.JwtUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class ApoAoto {


private final String URL_PREFIX = "/system";
private final Integer URL_LENGTH = 7;
@Autowired
private LogService logService;

@Around("@annotation(com.hk.annotation.AotoFile)")
public Object aotofile(ProceedingJoinPoint jp) throws Throwable {
    // 在切面方法中获取HttpServletRequest
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();

    log.info("拦截成功");

    //获取请求地址以及请求ip
    String url1 = request.getRequestURL().toString();
    String url = url1.substring(url1.indexOf(URL_PREFIX)+URL_LENGTH);
    String ip = IpUtils.getClientIp(request);


    String OperParam = JSONUtil.toJsonStr(IpLocationUtil.getLocation(ip));

    //获取当前被拦截方法的数据库操作类型与模块名称
    MethodSignature signature = (MethodSignature) jp.getSignature();
    AotoFile annotation = signature.getMethod().getAnnotation(AotoFile.class);
    OperationType operationType = annotation.value();
    String title = annotation.title();

    //获取请求方法名
    String method = signature.getName();

    //获取方法操作参数---实体对象
    Object[] args = jp.getArgs();
    String operParam= JSONUtil.toJsonStr(Arrays.toString(args));
    //准备赋值的数据
    LocalDateTime now = LocalDateTime.now();
    //格式化时间
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    // 格式化
    String formattedDateTime = now.format(formatter);

    UserUtlis utlis = BaseContext.getCurrent();
    String userName = utlis.getUserName();
    Long currentId = Long.valueOf(utlis.getUserId());
    String jsonResult="";
    String  errorMsg="";


    //获取返回结果
    try {
        Object proceed = jp.proceed();
         jsonResult= JSONUtil.toJsonStr(proceed);
    } catch (Throwable e) {
         errorMsg=  e.getMessage();
         jsonResult = "{}";
        // 抛出运行时异常以确保前端能收到错误响应
        throw new RuntimeException(e);
    }
    OperLog operLog = new OperLog();
    operLog.setTitle(title);
    if(operationType==OperationType.POST) {
        operLog.setBusinessType(1);
    }else if(operationType==OperationType.PUT) {
        operLog.setBusinessType(2);
    }else if(operationType==OperationType.DELETE) {
        operLog.setBusinessType(3);
    }
    operLog.setMethod(method);
    operLog.setRequestMethod(operationType.name());
    operLog.setOperatorType(1);
    operLog.setOperName(userName);
    operLog.setOperUrl(url);
    operLog.setOperIp(ip);
    operLog.setOperParam(operParam);
    operLog.setJsonResult(jsonResult);
    operLog.setErrorMsg(errorMsg);
    operLog.setOperTime(formattedDateTime);
    operLog.setStatus(0);
    log.info("操作日志上传完成:{}",operLog);
    logService.save(operLog);
    return jp.proceed();


}
}
